#include <WiFi.h>
#include <WiFiUdp.h> //引用以使用UDP

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif


const unsigned char color_model1[768] =
{
    0xbf, 0x00, 0x00, 0xbf, 0x03, 0x00, 0xbf, 0x06, 0x00, 0xbf, 0x0c, 0x00, 0xbf, 0x0f, 0x00, 0xbf, 0x16, 0x00, 0xbf, 0x19, 0x00, 0xbf, 0x1c, 0x00, 0xbf, 0x23, 0x00, 0xbf, 0x26, 0x00, 0xbf, 0x2c, 0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x33, 0x00, 0xbf, 0x39, 0x00, 0xbf, 0x3c, 0x00, 0xbf, 0x42, 0x00,
    0xbf, 0x46, 0x00, 0xbf, 0x49, 0x00, 0xbf, 0x4f, 0x00, 0xbf, 0x52, 0x00, 0xbf, 0x59, 0x00, 0xbf, 0x5c, 0x00, 0xbf, 0x5f, 0x00, 0xbf, 0x66, 0x00, 0xbf, 0x69, 0x00, 0xbf, 0x6f, 0x00, 0xbf, 0x72, 0x00, 0xbf, 0x75, 0x00, 0xbf, 0x7c, 0x00, 0xbf, 0x7f, 0x00, 0xbf, 0x85, 0x00, 0xbf, 0x89, 0x00,
    0xbf, 0x8f, 0x00, 0xbf, 0x92, 0x00, 0xbf, 0x95, 0x00, 0xbf, 0x9c, 0x00, 0xbf, 0x9f, 0x00, 0xbf, 0xa5, 0x00, 0xbf, 0xa8, 0x00, 0xbf, 0xac, 0x00, 0xbf, 0xb2, 0x00, 0xbf, 0xb5, 0x00, 0xbf, 0xbc, 0x00, 0xbf, 0xbf, 0x00, 0xbc, 0xbf, 0x00, 0xb5, 0xbf, 0x00, 0xb2, 0xbf, 0x00, 0xac, 0xbf, 0x00,
    0xa8, 0xbf, 0x00, 0xa5, 0xbf, 0x00, 0x9f, 0xbf, 0x00, 0x9c, 0xbf, 0x00, 0x95, 0xbf, 0x00, 0x92, 0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x89, 0xbf, 0x00, 0x85, 0xbf, 0x00, 0x7f, 0xbf, 0x00, 0x7c, 0xbf, 0x00, 0x79, 0xbf, 0x00, 0x72, 0xbf, 0x00, 0x6f, 0xbf, 0x00, 0x69, 0xbf, 0x00, 0x66, 0xbf, 0x00,
    0x5f, 0xbf, 0x00, 0x5c, 0xbf, 0x00, 0x59, 0xbf, 0x00, 0x52, 0xbf, 0x00, 0x4f, 0xbf, 0x00, 0x49, 0xbf, 0x00, 0x46, 0xbf, 0x00, 0x42, 0xbf, 0x00, 0x3c, 0xbf, 0x00, 0x39, 0xbf, 0x00, 0x33, 0xbf, 0x00, 0x2f, 0xbf, 0x00, 0x2c, 0xbf, 0x00, 0x26, 0xbf, 0x00, 0x23, 0xbf, 0x00, 0x1c, 0xbf, 0x00,
    0x19, 0xbf, 0x00, 0x16, 0xbf, 0x00, 0x0f, 0xbf, 0x00, 0x0c, 0xbf, 0x00, 0x06, 0xbf, 0x00, 0x03, 0xbf, 0x00, 0x00, 0xbf, 0x00, 0x00, 0xbf, 0x06, 0x00, 0xbf, 0x09, 0x00, 0xbf, 0x0f, 0x00, 0xbf, 0x13, 0x00, 0xbf, 0x16, 0x00, 0xbf, 0x1c, 0x00, 0xbf, 0x1f, 0x00, 0xbf, 0x26, 0x00, 0xbf, 0x29,
    0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x33, 0x00, 0xbf, 0x36, 0x00, 0xbf, 0x3c, 0x00, 0xbf, 0x3f, 0x00, 0xbf, 0x46, 0x00, 0xbf, 0x49, 0x00, 0xbf, 0x4c, 0x00, 0xbf, 0x52, 0x00, 0xbf, 0x56, 0x00, 0xbf, 0x5c, 0x00, 0xbf, 0x5f, 0x00, 0xbf, 0x62, 0x00, 0xbf, 0x69, 0x00, 0xbf, 0x6c, 0x00, 0xbf, 0x72,
    0x00, 0xbf, 0x75, 0x00, 0xbf, 0x79, 0x00, 0xbf, 0x7f, 0x00, 0xbf, 0x82, 0x00, 0xbf, 0x89, 0x00, 0xbf, 0x8c, 0x00, 0xbf, 0x8f, 0x00, 0xbf, 0x95, 0x00, 0xbf, 0x99, 0x00, 0xbf, 0x9f, 0x00, 0xbf, 0xa2, 0x00, 0xbf, 0xa5, 0x00, 0xbf, 0xac, 0x00, 0xbf, 0xaf, 0x00, 0xbf, 0xb5, 0x00, 0xbf, 0xb8,
    0x00, 0xbf, 0xbf, 0x00, 0xbc, 0xbf, 0x00, 0xb8, 0xbf, 0x00, 0xb2, 0xbf, 0x00, 0xaf, 0xbf, 0x00, 0xa8, 0xbf, 0x00, 0xa5, 0xbf, 0x00, 0xa2, 0xbf, 0x00, 0x9c, 0xbf, 0x00, 0x99, 0xbf, 0x00, 0x92, 0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x8c, 0xbf, 0x00, 0x85, 0xbf, 0x00, 0x82, 0xbf, 0x00, 0x7c, 0xbf,
    0x00, 0x79, 0xbf, 0x00, 0x75, 0xbf, 0x00, 0x6f, 0xbf, 0x00, 0x6c, 0xbf, 0x00, 0x66, 0xbf, 0x00, 0x62, 0xbf, 0x00, 0x5f, 0xbf, 0x00, 0x59, 0xbf, 0x00, 0x56, 0xbf, 0x00, 0x4f, 0xbf, 0x00, 0x4c, 0xbf, 0x00, 0x49, 0xbf, 0x00, 0x42, 0xbf, 0x00, 0x3f, 0xbf, 0x00, 0x39, 0xbf, 0x00, 0x36, 0xbf,
    0x00, 0x2f, 0xbf, 0x00, 0x2c, 0xbf, 0x00, 0x29, 0xbf, 0x00, 0x23, 0xbf, 0x00, 0x1f, 0xbf, 0x00, 0x19, 0xbf, 0x00, 0x16, 0xbf, 0x00, 0x13, 0xbf, 0x00, 0x0c, 0xbf, 0x00, 0x09, 0xbf, 0x00, 0x03, 0xbf, 0x00, 0x00, 0xbf, 0x03, 0x00, 0xbf, 0x09, 0x00, 0xbf, 0x0c, 0x00, 0xbf, 0x13, 0x00, 0xbf,
    0x16, 0x00, 0xbf, 0x19, 0x00, 0xbf, 0x1f, 0x00, 0xbf, 0x23, 0x00, 0xbf, 0x29, 0x00, 0xbf, 0x2c, 0x00, 0xbf, 0x2f, 0x00, 0xbf, 0x36, 0x00, 0xbf, 0x39, 0x00, 0xbf, 0x3f, 0x00, 0xbf, 0x42, 0x00, 0xbf, 0x46, 0x00, 0xbf, 0x4c, 0x00, 0xbf, 0x4f, 0x00, 0xbf, 0x56, 0x00, 0xbf, 0x59, 0x00, 0xbf,
    0x5f, 0x00, 0xbf, 0x62, 0x00, 0xbf, 0x66, 0x00, 0xbf, 0x6c, 0x00, 0xbf, 0x6f, 0x00, 0xbf, 0x75, 0x00, 0xbf, 0x79, 0x00, 0xbf, 0x7c, 0x00, 0xbf, 0x82, 0x00, 0xbf, 0x85, 0x00, 0xbf, 0x8c, 0x00, 0xbf, 0x8f, 0x00, 0xbf, 0x92, 0x00, 0xbf, 0x99, 0x00, 0xbf, 0x9c, 0x00, 0xbf, 0xa2, 0x00, 0xbf,
    0xa5, 0x00, 0xbf, 0xa8, 0x00, 0xbf, 0xaf, 0x00, 0xbf, 0xb2, 0x00, 0xbf, 0xb8, 0x00, 0xbf, 0xbc, 0x00, 0xbf, 0xbf, 0x00, 0xbf, 0xbf, 0x00, 0xb8, 0xbf, 0x00, 0xb5, 0xbf, 0x00, 0xaf, 0xbf, 0x00, 0xac, 0xbf, 0x00, 0xa8, 0xbf, 0x00, 0xa2, 0xbf, 0x00, 0x9f, 0xbf, 0x00, 0x99, 0xbf, 0x00, 0x95,
    0xbf, 0x00, 0x8f, 0xbf, 0x00, 0x8c, 0xbf, 0x00, 0x89, 0xbf, 0x00, 0x82, 0xbf, 0x00, 0x7f, 0xbf, 0x00, 0x79, 0xbf, 0x00, 0x75, 0xbf, 0x00, 0x72, 0xbf, 0x00, 0x6c, 0xbf, 0x00, 0x69, 0xbf, 0x00, 0x62, 0xbf, 0x00, 0x5f, 0xbf, 0x00, 0x5c, 0xbf, 0x00, 0x56, 0xbf, 0x00, 0x52, 0xbf, 0x00, 0x4c,
    0xbf, 0x00, 0x49, 0xbf, 0x00, 0x46, 0xbf, 0x00, 0x3f, 0xbf, 0x00, 0x3c, 0xbf, 0x00, 0x36, 0xbf, 0x00, 0x33, 0xbf, 0x00, 0x2f, 0xbf, 0x00, 0x29, 0xbf, 0x00, 0x26, 0xbf, 0x00, 0x1f, 0xbf, 0x00, 0x1c, 0xbf, 0x00, 0x19, 0xbf, 0x00, 0x13, 0xbf, 0x00, 0x0f, 0xbf, 0x00, 0x09, 0xbf, 0x00, 0x06
};

#define ADC_PIN   4     //定义旋钮IO
#define LED_PIN   27    //定义LED点阵 IO
#define LED_COUNT 256   //定义LED数


//wifi账号和密码
const char *ssid = "求约得密码";
const char *password = "1234abcd!!!";
unsigned int localUdpPort = 4569; //本地端口号（arduino端）
WiFiUDP Udp;                      //创建UDP对象

const unsigned int time_len = 10000;    //定时器定时时长
void initTime(unsigned int us_time);
void IRAM_ATTR onTimer();
void showModel_1(int speed,bool vh);
int iToLed(int i);


hw_timer_t*   mTimer= NULL;   //预先定义一个指针来存放定时器的位置
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);  //全彩LED的型号和参数

int analog_current,analog_last = 0;

void setup() 
{
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif  
  strip.begin();           // 初始化对象    
  
  for(int ledPos = 0;ledPos < LED_COUNT;ledPos ++)
    strip.setPixelColor(ledPos, 100, 100, 100);    
  strip.setBrightness(5); // 设置灯带总体亮度
  strip.show();  
  Serial.begin(115200);
  pinMode(ADC_PIN,INPUT);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (!WiFi.isConnected())
  {
    delay(500);
    Serial.print(".");
  }
  Udp.begin(localUdpPort); //启用UDP监听以接收数据
  Serial.print("Connected for IP Address:");
  Serial.print(WiFi.localIP());
  Serial.print("   and   listen Port:");
  Serial.println(localUdpPort);
  initTime(100000);
  
  //showModel_1(16,0);
}

void loop() 
{
//  int packetSize = Udp.parsePacket(); //获取当前队首数据包长度
//  if (packetSize)                     //如果有数据可用
//  {
//    char buf[packetSize];
//    Udp.read(buf, packetSize); //读取当前包数据
//    Serial.print("size: ");
//    Serial.print(packetSize);
//    Serial.print("Received: ");
//    Serial.println(buf);
//    char *ptrPos = 0;
//    for(int i = 0;i < packetSize;i ++)  //查找帧首
//    {
//      ptrPos = buf + i;
//      if(*ptrPos == 0x69 && *(ptrPos+1) == 0xaa)  //找到帧首位置
//      {
//        ptrPos++;   ptrPos++;   //去掉帧首
//        char dataPos = *ptrPos++; //得到数据类型 0(0-4*16)、 0(4*16-8*16)、 2(8*16-12*16)、 3(12*16-16*16)、 4(设置整体颜色和亮度)、 5(调节最大亮度)
//        if(dataPos >= 0 && dataPos <= 3)   //设置led显示内容，实例：69 aa 00 ff 12 12 13 ... ... ... 
//        {
//          if(packetSize < 259)  break;
//          dataPos = dataPos*64;     //计算数据偏移量
//          for(int ledPos = 0;ledPos < 64;ledPos ++)
//          {
//            int pos = dataPos + ledPos;
//            int white = *ptrPos++;
//            int red = *ptrPos++;
//            int green = *ptrPos++;
//            int blue = *ptrPos++; 
//            strip.setPixelColor(pos, red, green, blue);
//            Serial.printf("set led pos: %d   R:%d  G:%d  B:%d \n",pos,red,green,blue);
//          }
//          strip.show();
//          break;
//        }
//        else if(dataPos == 4)     //设置led整体颜色，实例：69 aa 04 00 ff 00
//        {
//          if(packetSize < 6)  break;
//          int red = *ptrPos++;
//          int green = *ptrPos++;
//          int blue = *ptrPos++; 
//          for(int ledPos = 0;ledPos < LED_COUNT;ledPos ++)
//            strip.setPixelColor(ledPos, red, green, blue);
//          strip.show();
//        }
//        else if(dataPos == 5)   //设置led整体亮度，实例：69 aa 05 ff (ff全亮 00全暗)
//        {
//          if(packetSize < 4)  break;
//          int ledLight = *ptrPos++;
//          strip.setBrightness(ledLight);
//          strip.show();
//          Serial.printf("ledLight: %d \n",ledLight);
//          
//        }
//      }
//    }
//  }
//  else
  
  static bool flag = 0;
  static int speed = 1000000;
  if(scanKey(23))
  {
    if(flag)
    {
      strip.setBrightness(20);
    }
    else
    {
      strip.setBrightness(80);
    }
    speed -= 100000;
    timerAlarmWrite(mTimer,speed,true);      //定时：操作的定时器 定时时长 数值是否重载【周期定时？】
    strip.show();
    flag = !flag;
  }
}

void initTime(unsigned int us_time) //定时器初始化函数
{
  mTimer = timerBegin(0,80,true);             //备用知识：定时器的型号选用   预分频【主频：80MHz】  定时器上下计数【true？】
  timerAttachInterrupt(mTimer,&onTimer,true); //初始化完毕候，将定时器连接到中断：定时器地址指针,中断处理函数,中断边沿触发类型
  timerAlarmWrite(mTimer,us_time,true);      //定时：操作的定时器 定时时长 数值是否重载【周期定时？】
  timerAlarmEnable(mTimer);                   //开始启动： 启动哪一个定时器？
}

//定义中断函数：【中断应加载到IRAM中，且无返回值】
void IRAM_ATTR onTimer()
{
  
  showModel_1(16,0);
}

void showModel_1(int speed,bool vh)      //七彩颜色循环滚动
{
    static int offset = 0;
    offset += speed;
    if(offset > 256)    offset -= 256;
    for(int i = 0;i < 256;i ++)
    {
        int ledPos = i%16*16 + i/16;
        int pos1 = (ledPos+offset)*3;
        int pos2 = pos1 +1;
        int pos3 = pos1 +2;
        if(pos1 >= 768) pos1 -= 768;
        if(pos2 >= 768) pos2 -= 768;
        if(pos3 >= 768) pos3 -= 768;
        unsigned char r = color_model1[pos1];
        unsigned char g = color_model1[pos2];
        unsigned char b = color_model1[pos3];
        strip.setPixelColor(iToLed(i), r, g, b);
    }
    strip.show();
}

int iToLed(int i)
{
  if((i/16)%2)
  {
    int line = i/16;
    int led = (line + 1)*16 - i%16;
    return led;
  }
  return i; 
}


bool scanKey(int pin)   //按键扫描程序           
{
  if(digitalRead(pin) == 1) //有按键按下
  {
    delay(15);  //延时去抖动
    if(digitalRead(pin) == 1) 
    {                
      while(digitalRead(pin) == 1); //等待按键松手
      return 1; 
    }
  }
  return 0;
}
